#ifndef SERVER_HH
# define SERVER_HH

//auto_ptr for client class
#include <boost/shared_ptr.hpp>

# include <boost/thread.hpp>
# include <boost/asio.hpp>
# include <boost/array.hpp>
# include <boost/unordered_map.hpp>

# include <tbb/concurrent_hash_map.h>

//Only here to have timers, to remove when new timer system is up
# include <SDL/SDL.h>

# include "rts-thread.hh"
# include "fps-thread.hh"
# include "misc/obj-vect.hh"

// includes for octree
# include "octree/octree_rts.hh"
# include "map/map.hh"

// includes for config file
# include "config/conf_parser.hh"

# include "physic/physic.hh"
# include "physic/fps-zone.hh"

using boost::asio::ip::tcp;

#include "misc/database.hh"
#include "client.hh"

class Listener;

class Server
{
public:
  Server (Database* db);
  ~Server ();
  void start ();
  void start (std::string filename);

  tcp::acceptor& acc () { return acc_; }
  boost::asio::io_service& ios () { return ios_; }
  tbb::concurrent_hash_map<int, boost::shared_ptr<Client> >* clientlist () { return &cl_; }
  GameThread* gt () const { return gt_; }

  Database* database () { return db_; }
  ObjVect* objvect () { return objvect_; }

  void remove_client (int clientid);
  void new_client (boost::shared_ptr<Client> c);

  //sending functions at connection time
  void send_objects (const boost::shared_ptr<Client>& c);
  void send_zones (const boost::shared_ptr<Client>& c);

  //add a FpsZone
  void add_zone (FpsZone* z);

  void init_rules (std::string filename);
  void init_map ();

  int nbclients () const { return nbclients_; }

  void ask_fps (FpsZone* z, int playerid);

  void move_obj (Object* obj, FpsZone* z);

  GameManager* gm () const { return gm_; }
protected:
  boost::asio::io_service ios_;
  tcp::acceptor acc_;

  //to give to game's thread
  tbb::concurrent_hash_map<int, boost::shared_ptr<Client> > cl_;
  tbb::concurrent_hash_map<FpsZone*, FpsThread*> fps_games_; 
  
  Database* db_;

  Listener* l_;

  //to give to game's thread
  //Physics side
  ObjVect* objvect_;

  int nbclients_;

  GameThread* gt_;
  GameManager* gm_;
};

#endif /// !SERVER_HH
